package su.samcom.calc.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import su.samcom.calc.controller.chart.PriceCell;
import su.samcom.calc.controller.chart.PriceChart;
import su.samcom.calc.controller.chart.PriceRow;
import su.samcom.calc.controller.form.PricingForm;
import su.samcom.calc.controller.validator.CalculatorFormValidator;
import su.samcom.calc.controller.validator.PricingFormValidator;
import su.samcom.calc.exception.RouteNotFoundException;
import su.samcom.calc.model.dao.LocationDao;
import su.samcom.calc.model.entity.Country;
import su.samcom.calc.model.entity.Location;
import su.samcom.calc.model.entity.Price;
import su.samcom.calc.service.CalculatorService;
import su.samcom.calc.service.CalculatorServiceImpl;
import su.samcom.calc.service.LocationService;
import su.samcom.calc.service.util.CalculatorUtil;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: Владислав
 * Date: 28.11.13
 * Time: 23:32
 * To change this template use File | Settings | File Templates.
 */
@Controller
@RequestMapping(value = "/pricing")
public class PricingController {

    @Autowired
    CalculatorService calculatorService;

    @Autowired
    LocationService locationService;

    @RequestMapping(method = RequestMethod.GET)
    public String cargoPricesPage(@ModelAttribute PricingForm pricingForm, Model model){
        List<Country> countries = locationService.getCountries();
        model.addAttribute("countries", countries);
        return "pricing.pricing";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String cargoPricesPagePost(@ModelAttribute PricingForm pricingForm, Model model){
        List<Country> countries = locationService.getCountries();
        model.addAttribute("countries", countries);

        Location locationFrom = locationService.getLocation(pricingForm.getLocationFrom(), pricingForm.getCountryFromId());
        Location locationTo = locationService.getLocation(pricingForm.getLocationTo(), pricingForm.getCountryToId());

        if(!PricingFormValidator.validateLocation(locationFrom, locationTo, model) |
                !PricingFormValidator.validate(pricingForm, model)){
            return "pricing.pricing";
        }

        if (locationFrom != null && locationTo != null){
            model.addAttribute("locationFromName", locationFrom.getName());
            model.addAttribute("locationToName", locationTo.getName());
            model.addAttribute("locationFromId", locationFrom.getId());
            model.addAttribute("locationToId", locationTo.getId());
        }
        return "pricing.pricing";
    }

    @RequestMapping(value = "/cargo-price/chart/json", method = RequestMethod.POST)
    public @ResponseBody Object[] cargoPricesChartJson(@RequestParam Long locationFromId, @RequestParam Long locationToId, Model model){
        List<Price> generalCargoPrices = Collections.<Price>emptyList();
        List<Price> separateCargoPrices = Collections.<Price>emptyList();

        try {
            generalCargoPrices = calculatorService.getCargoPrices(locationFromId, locationToId, CalculatorServiceImpl.CargoType.GENERAL);
        } catch (RouteNotFoundException e) {
        }
        Chart generalCargoChart = new Chart();
        for(Price price : generalCargoPrices){
            double percent = CalculatorUtil.calculateLoadedPercent(price);
            generalCargoChart.addPoint(percent, price.getPrice());
        }

        try {
            separateCargoPrices = calculatorService.getCargoPrices(locationFromId, locationToId, CalculatorServiceImpl.CargoType.SEPARATE);
        } catch (RouteNotFoundException e) {
        }
        Chart separateCargoChart = new Chart();
        for(Price price : separateCargoPrices){
            double percent = CalculatorUtil.calculateLoadedPercent(price);
            separateCargoChart.addPoint(percent, price.getPrice());
        }

        List charts = new ArrayList();
        charts.add(generalCargoChart.getPoints());
        charts.add(separateCargoChart.getPoints());

        return charts.toArray();
    }

    @RequestMapping(value = "/cargo-price/table/json", method = RequestMethod.GET)
    public @ResponseBody PriceChart cargoPriceTableJson(@RequestParam Long locationFromId, @RequestParam Long locationToId, @RequestParam CalculatorServiceImpl.CargoType cargoType, Model model){
        List<Price> prices = Collections.<Price>emptyList();
        try {
            prices = calculatorService.getCargoPrices(locationFromId, locationToId, cargoType);
        } catch (RouteNotFoundException e) {
            return new PriceChart();
        }

        List<PriceRow> rows = new ArrayList<PriceRow>();
        DecimalFormat zeroDecimalFormat = new DecimalFormat("0.00");
        DecimalFormat zero2DecimalFormat = new DecimalFormat("0.00");
        DecimalFormat zero3DecimalFormat = new DecimalFormat("0.000");
        for(Price price: prices){
            Double percent = CalculatorUtil.calculateLoadedPercent(price);

            PriceCell cell = new PriceCell();
            cell.setId(Long.toString(price.getId()));
            cell.setCbm(zeroDecimalFormat.format(price.getCbm()));
            cell.setLength(zero2DecimalFormat.format(price.getLength()));
            cell.setWeight(zero3DecimalFormat.format(price.getWeight()));
            cell.setName(price.getName());
            cell.setPrice(Integer.toString(price.getPrice()));
            cell.setPercent(zero2DecimalFormat.format(percent));

            PriceRow row = new PriceRow();
            row.setId(price.getId());
            row.setCell(cell);

            rows.add(row);
        }

        PriceChart chart = new PriceChart();
        chart.setPage(1);
        chart.setRecords(prices.size());
        chart.setTotal(prices.size());
        chart.setRows(rows);

        return chart;
    }
}
